// File: jmcomic-core/src/main/java/dev/jukomu/common/util/file/ZipUtils.java
package dev.jukomu.common.util.file;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipUtils {

    /**
     * 压缩文件夹内容到ZIP文件。
     *
     * @param srcFolderPath   源文件夹路径
     * @param destZipFilePath 目标ZIP文件路径
     * @throws IOException 如果发生IO错误
     */
    public static void zipFolder(String srcFolderPath, String destZipFilePath) throws IOException {
        Path source = Paths.get(srcFolderPath);
        Path destination = Paths.get(destZipFilePath);

        FileUtils.mkdirIfNotExists(FileUtils.getDirPath(destZipFilePath, false)); // Ensure parent dir exists

        try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(destination))) {
            Files.walk(source)
                    .filter(path -> !Files.isDirectory(path)) // 只压缩文件
                    .forEach(path -> {
                        ZipEntry zipEntry = new ZipEntry(source.relativize(path).toString());
                        try {
                            zos.putNextEntry(zipEntry);
                            Files.copy(path, zos);
                            zos.closeEntry();
                        } catch (IOException e) {
                            // Consider logging this error
                            throw new RuntimeException("Failed to zip file: " + path, e);
                        }
                    });
        }
    }

    /**
     * 从ZIP文件解压所有内容到指定文件夹。
     *
     * @param srcZipFilePath 源ZIP文件路径
     * @param destFolderPath 目标文件夹路径
     * @throws IOException 如果发生IO错误
     */
    public static void unzipFile(String srcZipFilePath, String destFolderPath) throws IOException {
        Path destinationDir = Paths.get(destFolderPath);
        FileUtils.mkdirIfNotExists(destFolderPath); // Ensure destination directory exists

        try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(Paths.get(srcZipFilePath)))) {
            ZipEntry zipEntry = zis.getNextEntry();
            while (zipEntry != null) {
                Path newFilePath = destinationDir.resolve(zipEntry.getName());
                if (zipEntry.isDirectory()) {
                    FileUtils.mkdirIfNotExists(newFilePath.toString());
                } else {
                    FileUtils.mkdirIfNotExists(newFilePath.getParent().toString()); // Ensure parent dir exists for file
                    Files.copy(zis, newFilePath);
                }
                zis.closeEntry();
                zipEntry = zis.getNextEntry();
            }
        }
    }
}